home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
batchut
/
batcsh10.zip
/
bat2csh.l
< prev
next >
Wrap
Text File
|
1994-01-12
|
18KB
|
709 lines
%{
/**************************************************************************/
/* MODULE: bat2csh.l */
/* PURPOSE: converts dos batch files to unix csh files */
/* AUTHOR: Bill Pierpoint */
/* LEX: FLEX Version 2.3.7 */
/* COMPILER: Borland C Version 3.1 */
/* COPYRIGHT: None. Public Domain. */
/* VERSION: 1.00 */
/* RELEASE: January 12, 1994 */
/**************************************************************************/
#include <stdc.h>
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#define putstr(s) fputs((s), stdout)
#define puttab() fputc('\t', stdout)
#define putln() fputc('\n', stdout)
#define token(t) (t)
#define ckeol(t) do { if((t)==EOL) { puts(" ### SYNTAX ERROR ###"); \
errorcount++; return;} } while(0)
#define cktok(t, x) do { if((t)!=(x)) { puts(" ### SYNTAX ERROR ###"); \
errorcount++; eattokens(); return;} } while(0)
typedef struct
{
int token;
void (*fn)(void);
} FNTBL;
#define STRBUFSIZE 129
char textbuf[STRBUFSIZE];
/**************************************************************************/
/* token enumeration */
/**************************************************************************/
enum {
OTHER=1,
EOL,
SPACE,
VARIABLE,
PARAMETER,
WORD,
INIT_CALL,
INIT_ECHO,
INIT_FOR,
INIT_GOTO,
INIT_IF,
INIT_PATH,
INIT_PAUSE,
INIT_REM,
INIT_SET,
INIT_SHIFT,
INIT_LABEL,
INIT_COMMAND,
ECHO_ON,
ECHO_OFF,
ECHO_DOT,
IF_NOT,
IF_ERRORLEVEL,
IF_EXIST,
FOR_VARIABLE,
FOR_IN,
FOR_WORDLIST,
FOR_DO
};
/**************************************************************************/
/* function prototypes */
/**************************************************************************/
/* support functions */
char *cvt_parameter(char *s);
char *cvt_variable(char *s);
char *cvt_for_variable(char *s);
char *cvt_set_variable(int token);
char *cvt_token(int token, char *s);
int dispatch(void);
void indent(void);
int lex(void);
void putbacktoken(void);
void puttokln(int token, char *start, char *end);
int reporterrors(void);
void terminate(void);
char *tr(char *s, int oldch, int newch);
/* keyword functions */
void kw_call(void);
void kw_command(void);
void kw_echo(void);
void kw_for(void);
void kw_goto(void);
void kw_if(void);
void kw_label(void);
void kw_ln(void);
void kw_path(void);
void kw_pause(void);
void kw_remark(void);
void kw_set(void);
void kw_shift(void);
%}
digit [0-9]
delim [ \t=;]
name [-{}()&#!~$a-zA-Z0-9]
legal [!-$&-:<>-~]
other .
%x ECHOS
%x TEXT
%x FOR
%%
<INITIAL>^"@" ;
<INITIAL>call return token(INIT_CALL);
<INITIAL>echo return token(INIT_ECHO);
<INITIAL>for return token(INIT_FOR);
<INITIAL>goto return token(INIT_GOTO);
<INITIAL>if return token(INIT_IF);
<INITIAL>pause return token(INIT_PAUSE);
<INITIAL>rem return token(INIT_REM);
<INITIAL>set return token(INIT_SET);
<INITIAL>path return token(INIT_PATH);
<INITIAL>shift return token(INIT_SHIFT);
<INITIAL>^":"{name}+ return token(INIT_LABEL);
<INITIAL>^":" return token(INIT_REM);
<INITIAL>{name}+ return token(INIT_COMMAND);
<ECHOS>on return token(ECHO_ON);
<ECHOS>off return token(ECHO_OFF);
<ECHOS>"." return token(ECHO_DOT);
<TEXT>not return token(IF_NOT);
<TEXT>errorlevel return token(IF_ERRORLEVEL);
<TEXT>exist return token(IF_EXIST);
<TEXT>{delim}+ return token(SPACE);
<TEXT>"%"{name}+"%" return token(VARIABLE);
<TEXT>"%"{digit} return token(PARAMETER);
<TEXT,FOR>%%{name}+ return token(FOR_VARIABLE);
<FOR>in return token(FOR_IN);
<FOR>do return token(FOR_DO);
<FOR>"("[^)]+")" return token(FOR_WORDLIST);
<INITIAL,ECHOS,TEXT,FOR>"\n" return token(EOL);
<INITIAL,ECHOS,FOR>{delim}+ ;
<ECHOS,TEXT>{legal}+ return token(WORD);
<INITIAL,ECHOS,TEXT,FOR>{other} return token(OTHER);
%%
#ifdef __BORLANDC__
#pragma option -w
#endif
/**************************************************************************/
/* global variables */
/**************************************************************************/
int cmdtoken; /* first token in each batch line */
int errorcount=0; /* syntax error counter */
int errorlevelflag=0; /* control use of "set errorlevel=$status" */
int indentlevel=0; /* indent level of output */
/**************************************************************************/
/* support functions */
/**************************************************************************/
/* report any errors */
int reporterrors()
{
char s[7];
if (errorcount) {
itoa(errorcount, s, 10);
fputs("\n\nNUMBER OF ERRORS = ", stderr);
fputs(s, stderr);
fputs("\n\n", stderr);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
/* abnormal termination */
void terminate(void)
{
putln();
puts(" ### PREMATURE END-OF-FILE ###");
errorcount++;
exit(reporterrors());
}
/* wrapper for yylex */
int lex(void)
{
int result; /* return result */
static int count=0; /* count number of times yylex returns 0 */
result = yylex();
if (!result) {
if (count==1) {
terminate();
} else { /* handle possible premature eof */
count++;
result = EOL;
}
}
return result;
}
/* indent output based on global indentlevel */
void indent(void)
{
int i;
for (i=0; i<indentlevel; i++) puttab();
}
/* put token back to input stream */
/* note: flex 2.3.7 yyless(0) not available in section 3 */
void putbacktoken(void)
{
int i;
for (i=yyleng-1; i>=0; i--) {
unput(yytext[i]);
}
}
/* translate character in string s */
char *tr(char *s, int oldch, int newch)
{
char *sp = s;
do {
if (*sp==oldch) *sp=newch;
} while (*sp++);
return s;
}
/* convert replaceable parameter, e.g. %1 -> $1 */
char *cvt_parameter(char *s)
{
strcpy(textbuf, s);
*textbuf='$';
return textbuf;
}
/* convert variable, e.g. %PATH% -> ${path} */
char *cvt_variable(char *s)
{
char *sp;
strcpy(textbuf, "${");
sp = s;
sp++;
strncat(textbuf, sp, yyleng-2);
strcat(textbuf, "}");
return strlwr(textbuf);
}
/* convert variable used with 'for' keyword, e.g. %%F -> ${f} */
char *cvt_for_variable(char *s)
{
char *sp;
strcpy(textbuf, "${");
sp = s;
sp += 2;
strncat(textbuf, sp, yyleng-2);
strcat(textbuf, "}");
return strlwr(textbuf);
}
/* convert variable used with set keyword, e.g. ${f} -> f */
char *cvt_set_variable(int token)
{
int len;
switch(token) {
case VARIABLE:
case FOR_VARIABLE:
len = strlen(textbuf)-2;
memmove(textbuf, textbuf+2, len);
textbuf[len-1]='\0';
break;
default:
break;
}
return textbuf;
}
/* convert from batch format to csh format */
char *cvt_token(int token, char *s)
{
char *sp, *tp=textbuf;
switch(token) {
case PARAMETER:
if (s) cvt_parameter(s);
else cvt_parameter(yytext);
break;
case VARIABLE:
if (s) cvt_variable(s);
else cvt_variable(yytext);
break;
case FOR_VARIABLE:
if (s) cvt_for_variable(s);
else cvt_for_variable(yytext);
break;
case SPACE:
if (s) strcpy(textbuf, s);
else strcpy(textbuf, yytext);
/* translate delimiter if set or path */
if (cm